﻿using Microsoft.Extensions.Configuration;
using PclCSharp;
using PointCloudSharp;

namespace PCLCSharpTool
{
    public class Program
    {
        static void Main(string[] args)
        {
            //输入的点云对象
            PointCloudXYZ inputPointCloud = new PointCloudXYZ();
            //输出的点云对象
            PointCloudXYZ outputPointCloud = new PointCloudXYZ();

            var configuration = new ConfigurationBuilder()
                .SetBasePath(Directory.GetCurrentDirectory())
                .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
                .Build();

            var inputFilePath = args[0];
            var outputFilePath = args[2];
            Io.loadPlyFile(inputFilePath, inputPointCloud.PointCloudXYZPointer);
            var method = Convert.ToInt32(args[1]);
            switch (method)
            {
                // 体素下采样
                case 1:
                {
                    Filter.voxelDownSample(
                        inputPointCloud.PointCloudXYZPointer,
                        Convert.ToDouble(configuration["voxelDownSample:leafSize"]),
                        outputPointCloud.PointCloudXYZPointer
                    );
                    Io.savePlyFile(
                        outputFilePath,
                        outputPointCloud.PointCloudXYZPointer,
                        Convert.ToInt32(configuration["voxelDownSample:binaryMode"])
                    );
                    break;
                }
                // 近似体素下采样
                case 2:
                {
                    Filter.approximateVoxelDownSample(
                        inputPointCloud.PointCloudXYZPointer,
                        Convert.ToDouble(configuration["approximateVoxelDownSample:leafSize"]),
                        outputPointCloud.PointCloudXYZPointer
                    );
                    Io.savePlyFile(
                        outputFilePath,
                        outputPointCloud.PointCloudXYZPointer,
                        Convert.ToInt32(configuration["approximateVoxelDownSample:binaryMode"])
                    );
                    break;
                }
                // 均匀下采样
                case 3:
                {
                    Filter.uniformDownSample(
                        inputPointCloud.PointCloudXYZPointer,
                        Convert.ToDouble(configuration["uniformDownSample:radius"]),
                        outputPointCloud.PointCloudXYZPointer
                    );
                    Io.savePlyFile(
                        outputFilePath,
                        outputPointCloud.PointCloudXYZPointer,
                        Convert.ToInt32(configuration["uniformDownSample:binaryMode"])
                    );
                    break;
                }
                // 半径滤波
                case 4:
                {
                    Filter.radiusFilter(
                        inputPointCloud.PointCloudXYZPointer,
                        Convert.ToDouble(configuration["radiusFilter:radius"]),
                        Convert.ToInt32(configuration["radiusFilter:numThresh"]),
                        outputPointCloud.PointCloudXYZPointer
                    );
                    Io.savePlyFile(
                        outputFilePath,
                        outputPointCloud.PointCloudXYZPointer,
                        Convert.ToInt32(configuration["radiusFilter:binaryMode"])
                    );
                    break;
                }
                // 统计滤波
                case 5:
                {
                    Filter.staFilter(
                        inputPointCloud.PointCloudXYZPointer,
                        Convert.ToInt32(configuration["staFilter:neighborNum"]),
                        Convert.ToInt32(configuration["staFilter:Thresh"]),
                        outputPointCloud.PointCloudXYZPointer
                    );
                    Io.savePlyFile(
                        outputFilePath,
                        outputPointCloud.PointCloudXYZPointer,
                        Convert.ToInt32(configuration["staFilter:binaryMode"])
                    );
                    break;
                }
                // 欧式聚类
                case 6:
                {
                    Segmentation.euclideanCluster(
                        inputPointCloud.PointCloudXYZPointer,
                        Convert.ToDouble(configuration["euclideanCluster:distanceThresh"]),
                        Convert.ToInt32(configuration["euclideanCluster:MinClusterSize"]),
                        Convert.ToInt32(configuration["euclideanCluster:MaxClusterSize"]),
                        outputPointCloud.PointCloudXYZPointer
                    );
                    Io.savePlyFile(
                        outputFilePath,
                        outputPointCloud.PointCloudXYZPointer,
                        Convert.ToInt32(configuration["euclideanCluster:binaryMode"])
                    );
                    break;
                }
                // 区域生长
                case 7:
                {
                    Segmentation.modifiedGrowRegion(
                        inputPointCloud.PointCloudXYZPointer,
                        Convert.ToInt32(configuration["modifiedGrowRegion:neighborNum"]),
                        Convert.ToInt32(configuration["modifiedGrowRegion:smoothThresh"]),
                        float.Parse(configuration["modifiedGrowRegion:curvaThresh"]),
                        Convert.ToInt32(configuration["modifiedGrowRegion:MinClusterSize"]),
                        Convert.ToInt32(configuration["modifiedGrowRegion:MaxClusterSize"]),
                        outputPointCloud.PointCloudXYZPointer
                    );
                    Io.savePlyFile(
                        outputFilePath,
                        outputPointCloud.PointCloudXYZPointer,
                        Convert.ToInt32(configuration["modifiedGrowRegion:binaryMode"])
                    );
                    break;
                }
            }
        }
    }
}
